"use strict";

const utils = require("../utils");

/**
 * 特定于配置合并，将两个配置对象合并成一个新的配置对象
 *
 * @param {Object} config1 配置对象1
 * @param {Object} config2 配置对象2
 * @returns {Object} 新的配置对象（合并了配置1和配置2）
 */
module.exports = function mergeConfig(config1, config2) {
  config2 = config2 || {};
  const config = {};

  const valueFromConfig2Keys = ["url", "method", "data"];
  const mergeDeepPropertiesKeys = ["headers", "auth", "proxy", "params"];
  const defaultToConfig2Keys = [
    "baseURL",
    "url",
    "transformRequest",
    "transformResponse",
    "paramsSerializer",
    "timeout",
    "withCredentials",
    "adapter",
    "responseType",
    "xsrfCookieName",
    "xsrfHeaderName",
    "onUploadProgress",
    "onDownloadProgress",
    "maxContentLength",
    "maxBodyLength",
    "validateStatus",
    "maxRedirects",
    "httpAgent",
    "httpsAgent",
    "cancelToken",
    "socketPath",
    "responseEncoding",
  ];

  utils.forEach(valueFromConfig2Keys, function valueFromConfig2(prop) {
    if (!utils.isUndefined(config2[prop])) {
      config[prop] = config2[prop];
    }
  });

  utils.forEach(mergeDeepPropertiesKeys, function mergeDeepProperties(prop) {
    if (utils.isObject(config2[prop])) {
      config[prop] = utils.deepMerge(config1[prop], config2[prop]);
    } else if (!utils.isUndefined(config2[prop])) {
      config[prop] = config2[prop];
    } else if (utils.isObject(config1[prop])) {
      config[prop] = utils.deepMerge(config1[prop]);
    } else {
      config[prop] = config1[prop];
    }
  });

  utils.forEach(defaultToConfig2Keys, function defaultToConfig2(prop) {
    if (!utils.isUndefined(config2[prop])) {
      config[prop] = config2[prop];
    } else if (!utils.isUndefined(config1[prop])) {
      config[prop] = config1[prop];
    }
  });

  const axiosKeys = valueFromConfig2Keys
    .concat(mergeDeepPropertiesKeys)
    .concat(defaultToConfig2Keys);

  const otherKeys = Object.keys(config2).filter(function filterAxiosKeys(key) {
    return axiosKeys.indexOf(key) === -1;
  });

  utils.forEach(otherKeys, function otherKeysDefaultToConfig2(prop) {
    if (!utils.isUndefined(config2[prop])) {
      config[prop] = config2[prop];
    } else if (!utils.isUndefined(config1[prop])) {
      config[prop] = config1[prop];
    }
  });

  return config;
};
